using GameLogic;
using static GameLogic.SocketDefinition;
using System;
using TEngine;
using UnityEngine;
using System.Text.RegularExpressions;

namespace GameLogic
{
    public partial class SocketProxy
    {
        public static async void SocketLogin(
            LOGIN_TYPE accountType,
            string loginID,
            string password,
            string appStr,
            string market,
            string unityResPath = "",
            string mac1 = "",
            string mac2 = "",
            string deviceID = "",
            string inviteCode = ""
            )
        {
            LOGIN_FLAG plat = LOGIN_FLAG.MODE_MOBILE;
            LOGIN_FLAG type = LOGIN_FLAG.TYPE_UNBIND;

            var config = await Settings.Instance.GetGameConfig();

            SocketLoginPacket packet = new SocketLoginPacket()
            {
                accountType = (uint)accountType,
                loginID = loginID,
                password = password,
                inviteCode = inviteCode,
                mac1 = mac1,
                mac2 = mac2,
                appStr = appStr,
                market = market,
                deviceID = deviceID,
                unityResPath = unityResPath,
                loginType = CalculateLoginType(accountType, plat, type),
                platform = (uint)config.platformID,
                appVersion = (uint)GameUtility.ConvertVersionToNumber(config.appVersion),
                unityVersion = (uint)GameUtility.ConvertVersionToNumber(config.unityVersion),
                devicename = UnityEngine.SystemInfo.deviceName,
                os = GetOSData(),
                timeStamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString(),
            };
            ModuleSystem.GetModule<ISocketProxy>().SendSocketData(packet);
        }

        private static uint GetOSData()
        {
            uint type = (uint)GetDeviceOSType();
            uint version = (uint)GetMajorSystemVersion();
            return type * 1000 + version;
        }

        public static int GetMajorSystemVersion()
        {
            string osInfo = UnityEngine.SystemInfo.operatingSystem;

            // 匹配版本号开头的数字
            Match match = Regex.Match(osInfo, @"^(\d+)");
            if (!match.Success)
            {
                // 尝试匹配其他格式的版本号
                match = Regex.Match(osInfo, @"\b(\d+)(?:\.\d+)+");
            }

            if (match.Success && int.TryParse(match.Groups[1].Value, out int majorVersion))
            {
                return majorVersion;
            }

            // 默认返回值
            return 0;
        }

        public static DEVICE_OS_TYPE GetDeviceOSType()
        {
#if UNITY_ANDROID
                    return DEVICE_OS_TYPE.Android;
#elif UNITY_IOS
                    return DEVICE_OS_TYPE.iOS;
#elif UNITY_WEBGL
                    return DEVICE_OS_TYPE.Chrome;
#else
            switch (UnityEngine.Application.platform)
            {
                case RuntimePlatform.WindowsEditor:
                case RuntimePlatform.WindowsPlayer:
                    return DEVICE_OS_TYPE.Windows;
                case RuntimePlatform.OSXEditor:
                case RuntimePlatform.OSXPlayer:
                    return DEVICE_OS_TYPE.MacOrLinux;
                case RuntimePlatform.IPhonePlayer:
                    return DEVICE_OS_TYPE.iOS;
                case RuntimePlatform.Android:
                    return DEVICE_OS_TYPE.Android;
                case RuntimePlatform.WebGLPlayer:
                    return DEVICE_OS_TYPE.Chrome;
                default:
                    throw new NotSupportedException($"GetDeviceOSType '{UnityEngine.Application.platform.ToString()}' is not find.");
            }
#endif
        }


        /// <summary>
        /// 计算FLAG
        /// </summary>
        private static uint CalculateLoginType(LOGIN_TYPE accountType, LOGIN_FLAG plat = LOGIN_FLAG.MODE_MOBILE, LOGIN_FLAG type = LOGIN_FLAG.TYPE_UNBIND)
        {
            switch (accountType)
            {
                //手机
                case LOGIN_TYPE.MSG:
                case LOGIN_TYPE.AUTH:
                case LOGIN_TYPE.PHONE_NUM_AUTH:
                    type = LOGIN_FLAG.TYPE_PHONE;
                    break;
                default:
                    type = LOGIN_FLAG.TYPE_OPEN_ID;
                    break;
            }
            uint loginType = (uint)plat + (uint)type;
            return loginType;
        }
    }
}